<?php
/**
 * Created by JetBrains PhpStorm.
 * User: dodasso
 * Date: 7/28/13
 * Time: 5:35 PM
 * To change this template use File | Settings | File Templates.
 */

namespace inventory;

require_once(APP_ROOT . '/modules/log/log.php');
require_once(APP_ROOT . '/modules/log/logCommon.php');
require_once(APP_ROOT . '/modules/common/Utils.php');
require_once(APP_ROOT . '/modules/common/Common.php');
require_once(APP_ROOT . '/modules/common/Errors.php');
require_once(APP_ROOT . '/modules/common/SessionDto.php');
require_once(APP_ROOT . '/modules/common/User.php');
require_once(APP_ROOT . '/modules/common/Module.php');
require_once(APP_ROOT . '/modules/common/MeasuringUnit.php');
require_once(APP_ROOT . '/modules/common/LineOfBussines.php');
require_once(APP_ROOT . '/modules/inventory/InventoryObject.php');
require_once(APP_ROOT . '/modules/inventory/InventoryDtoDto.php');
require_once(APP_ROOT . '/modules/inventory/Location.php');
require_once(APP_ROOT . '/modules/inventory/Movement.php');
require_once(APP_ROOT . '/modules/inventory/MovementType.php');
require_once(APP_ROOT . '/modules/inventory/Warehouse.php');
require_once(APP_ROOT . '/modules/persistance/InventoryObjectPersistance.php');
require_once(APP_ROOT . '/modules/persistance/InventoryPersistance.php');
//require_once(APP_ROOT . '/modules/persistance/LocationPersistance.php');
//require_once(APP_ROOT . '/modules/persistance/MovementPersistance.php');
//require_once(APP_ROOT . '/modules/persistance/MovementTypePersistance.php');
//require_once(APP_ROOT . '/modules/persistance/WarehousePersistance.php');
require_once(APP_ROOT . '/modules/persistance/ModulePersistance.php');
require_once(APP_ROOT . '/modules/persistance/UserPersistance.php');
require_once(APP_ROOT . '/modules/persistance/MeasuringUnitPersistance.php');
require_once(APP_ROOT . '/modules/persistance/LineOfBussinesPersistance.php');

use common\CommonModule;
use log\Log;
use log\LogCommon;
use common\utils;
use common\Common;
use common\Errors;
use common\SessionDto;
use common\UserDto;
use common\ModuleDto;
use common\MeasuringUnitDto;
use common\LineOfBussinesDto;
use inventory\InventoryObjectDto;
use inventory\InventoryDto;
use inventory\Movement;
use inventory\MovementType;
use inventory\LocationDto;
use inventory\Warehouse;
use persistance\InventoryObjectPersistance;
use persistance\InventoryPersistance;
use persistance\LocationPersistance;
use persistance\MeasuringUnitPersistance;
use persistance\LineOfBussinesPersistance;
use persistance\MovementPersistance;
use persistance\MovementTypePersistance;
use persistance\SessionPersistance;
use persistance\WarehousePersistance;
use persistance\ModulePersistance;
use persistance\UserPersistance;

class InventoryModule {
    /**
     * @var SessionDto | null
     */
    private $session;

    /**
     * @var UserDto | null
     */
    private $user;

    /**
     * @var ModuleDto | null
     */
    private $module;

    /**
     * @var CommonModule|null
     */
    private $commonModule;

    /**
     * @var bool
     */
    private $initialized;

    public function __construct() {
        Log::LOG_INVENTORY_FB();

        $this->session      = null;
        $this->user         = null;
        $this->module       = null;
        $this->initialized  = false;
        $this->commonModule = null;

        Log::LOG_INVENTORY_FE();
    }

    public function __destruct() {
        Log::LOG_INVENTORY_FB();
        Log::LOG_INVENTORY_FE();
    }

    private function loadSession($sessionKey) {
        Log::LOG_INVENTORY_FB();

        if((is_null($sessionKey)) || (empty($sessionKey))) {
            Log::LOG_INVENTORY(LogCommon::logTypeError, 'Invalid parameters.');
            return false;
        }

        $rs = SessionPersistance::findByKey($sessionKey);
        if($rs['error'] != Errors::INTEGRAL_ERR_NONE) {
            Log::LOG_INVENTORY(LogCommon::logTypeError, 'Session not found. Key: ' .
                $sessionKey . '. [' . $rs['error'] . ']');
            return false;
        }

        $this->session = $rs['data'];

        Log::LOG_INVENTORY_FE();

        return true;
    }

    private function loadUserFromSession() {
        Log::LOG_INVENTORY_FB();

        if((is_null($this->session))) {
            Log::LOG_INVENTORY(LogCommon::logTypeError, 'Session not loaded.');
            return false;
        }

        $rs = UserPersistance::findById($this->session->userId);
        if($rs['error'] != Errors::INTEGRAL_ERR_NONE) {
            Log::LOG_INVENTORY(LogCommon::logTypeCritical, 'User from session not found. User Id: ' .
                $this->session->userId . ' Session key: ' . $this->session->key .
                '. [' . $rs['error'] . ']');
            return false;
        }
        $this->user = $rs['data'];

        Log::LOG_INVENTORY_FE();

        return true;
    }

    private function loadModule() {
        Log::LOG_INVENTORY_FB();

        $rs = ModulePersistance::findByType(Common::inventoryModule);
        if($rs['error'] != Errors::INTEGRAL_ERR_NONE) {
            Log::LOG_INVENTORY(LogCommon::logTypeError, 'Module not found. Id: ' .
                Common::inventoryModule . '. [' . $rs['error'] . ']');
            return false;
        }

        $this->module = $rs['data'];

        Log::LOG_INVENTORY_FE();

        return true;
    }

    private function isUserAuthorized() {
        Log::LOG_INVENTORY_FB();

        if((is_null($this->user)) || is_null($this->module)) {
            Log::LOG_INVENTORY(LogCommon::logTypeError, 'User not loaded.');
            return false;
        }

        Log::LOG_INVENTORY_FE();

        return ($this->module->isUserAuthorized($this->user));
    }

    public function initWithSessionKey($sessionKey) {
        if((is_null($sessionKey)) || (empty($sessionKey))) {
            Log::LOG_INVENTORY(LogCommon::logTypeError, 'Invalid parameters.');
            return false;
        }

        if(!$this->loadSessionWithKey($sessionKey)) {
            Log::LOG_INVENTORY(LogCommon::logTypeError, 'Unable to load sesison. Key ' .
                $sessionKey);
            return false;
        };

        if(!$this->loadUserFromSession($this->session)) {
            Log::LOG_INVENTORY(LogCommon::logTypeCritical, 'Unable to load user from sesison. Key ' .
                $this->session->key);
            return false;
        };

        if(!$this->loadModule()) {
            Log::LOG_INVENTORY(LogCommon::logTypeError, 'Unable to load module.');
            return false;
        };

        if(!$this->isUserAuthorized()) {
            Log::LOG_INVENTORY(LogCommon::logTypeSecurity, 'User not authorized to use this module');
            return false;
        }

        $this->commonModule = new CommonModule();
        $this->initialized = true;

        return true;
    }

    public function listLineOfBussiness() {
        Log::LOG_INVENTORY_FB();

        if(!$this->initialized) {
            Log::LOG_INVENTORY(LogCommon::logTypeError, 'Not initialized.');
            return Utils::buildResponse(array('error'=>Errors::INTEGRAL_ERR_INVENTORY_NOT_INITIALIZED,
                                              'data'=>''));
        }

        Log::LOG_INVENTORY_FE();

        return $this->commonModule->listLineOfBussiness();
    }

    public function listMovementTypes() {
        Log::LOG_INVENTORY_FB();

        if(!$this->initialized) {
            Log::LOG_INVENTORY(LogCommon::logTypeError, 'Not initialized.');
            return Utils::buildResponse(array('error'=>Errors::INTEGRAL_ERR_INVENTORY_NOT_INITIALIZED,
                                              'data'=>''));
        }

        $rs = MovementTypePersistance::listNotDeleted();
        if($rs['error'] != Errors::INTEGRAL_ERR_NONE) {
            Log::LOG_INVENTORY(LogCommon::logTypeError, 'Unable to list movement types.' .
                ' [' . $rs['error'] . ']');
            return Utils::buildResponse(array('error'=>Errors::INTEGRAL_ERR_INVENTORY_UNABLE_TO_LIST_MOVEMENT_TYPES,
                                              'data'=>''));
        }

        Log::LOG_INVENTORY_FE();

        return Utils::buildResponse(array('error'=>Errors::INTEGRAL_ERR_NONE, 'data'=>$rs['data']));
    }

    public function listInventoryObjects() {
        Log::LOG_INVENTORY_FB();

        if(!$this->initialized) {
            Log::LOG_INVENTORY(LogCommon::logTypeError, 'Not initialized.');
            return Utils::buildResponse(array('error'=>Errors::INTEGRAL_ERR_INVENTORY_NOT_INITIALIZED,
                                              'data'=>''));
        }

        $rs = InventoryObjectPersistance::listNotDeleted();
        if($rs['error'] != Errors::INTEGRAL_ERR_NONE) {
            Log::LOG_INVENTORY(LogCommon::logTypeError, 'Unable to list inventory objects.' .
                ' [' . $rs['error'] . ']');
            return Utils::buildResponse(array('error'=>Errors::INTEGRAL_ERR_INVENTORY_UNABLE_TO_LIST_INVENTORY_OBJECTS,
                                              'data'=>''));
        }

        Log::LOG_INVENTORY_FE();

        return Utils::buildResponse(array('error'=>Errors::INTEGRAL_ERR_NONE, 'data'=>$rs['data']));
    }

    public function findInventoryObjectById($id) {
        Log::LOG_INVENTORY_FB();

        if((is_null($id) || (!is_int($id)))) {
            Log::LOG_INVENTORY(LogCommon::logTypeError, 'Invalid parameters.');
            return Utils::buildResponse(array('error'=>Errors::INTEGRAL_ERR_INVALID_PARAMETERS,
                                              'data'=>''));
        }

        if(!$this->initialized) {
            Log::LOG_INVENTORY(LogCommon::logTypeError, 'Not initialized.');
            return Utils::buildResponse(array('error'=>Errors::INTEGRAL_ERR_INVENTORY_NOT_INITIALIZED,
                                              'data'=>''));
        }

        $rs = InventoryObjectPersistance::findById($id);
        if($rs['error'] != Errors::INTEGRAL_ERR_NONE) {
            Log::LOG_INVENTORY(LogCommon::logTypeError, 'Unable find inventory object. Id: ' .
                $id . '. [' . $rs['error'] . ']');
            return Utils::buildResponse(array('error'=>Errors::INTEGRAL_ERR_INVENTORY_UNABLE_TO_FIND_INVENTORY_OBJECT,
                                              'data'=>''));
        }

        Log::LOG_INVENTORY_FE();

        return Utils::buildResponse(array('error'=>Errors::INTEGRAL_ERR_NONE, 'data'=>$rs['data']));
    }

    public function findInventoryObjectByName($name) {
        Log::LOG_INVENTORY_FB();

        if((is_null($name) || (!is_string($name)))) {
            Log::LOG_INVENTORY(LogCommon::logTypeError, 'Invalid parameters.');
            return Utils::buildResponse(array('error'=>Errors::INTEGRAL_ERR_INVALID_PARAMETERS,
                                              'data'=>''));
        }

        if(!$this->initialized) {
            Log::LOG_INVENTORY(LogCommon::logTypeError, 'Not initialized.');
            return Utils::buildResponse(array('error'=>Errors::INTEGRAL_ERR_INVENTORY_NOT_INITIALIZED,
                                              'data'=>''));
        }

        $rs = InventoryObjectPersistance::findByName($name, true);
        if($rs['error'] != Errors::INTEGRAL_ERR_NONE) {
            Log::LOG_INVENTORY(LogCommon::logTypeError, 'Unable find inventory object. Name: ' .
                $name . '. [' . $rs['error'] . ']');
            return Utils::buildResponse(array('error'=>Errors::INTEGRAL_ERR_INVENTORY_UNABLE_TO_FIND_INVENTORY_OBJECT,
                                              'data'=>''));
        }

        Log::LOG_INVENTORY_FE();

        return Utils::buildResponse(array('error'=>Errors::INTEGRAL_ERR_NONE, 'data'=>$rs['data']));
    }
}